F�r diesen Algorithmus gilt vieles, was bereits zum Scroller_YUnlimited gesagt wurde. Sehen Sie sich deshalb unbedingt zuerst dessen Dokumentation an!

Der gro�e Unterschied besteht darin, da� die Bitmap nicht mehr doppelt hoch ist. Die Bitmaph�he betr�gt 288 Pixel (256 + 32). Wir werden auch nicht mehr doppelt blitten, und dadurch ist dieser Alogrithmus doppelt so schnell. Die Tatsache, da� wir nicht mehr doppelt blitten, ist auch der einzige gro�e Unterschied zum Scroller_YUnlimited Algorithmus. Nehmen wir an, wir sind eine halbe Bitmaph�he runter gescrollt. Das sieht dann bei den beiden Algorithmen etwa so aus:

Wie man an diesem Bild sieht, geht beim Scroller_YUnlimited2 der aktuelle und sichtbare Bereich �ber die Bitmapgrenzen hinaus. Das darf nat�rlich nicht sein, weil sich dort nichts befindet oder besser gesagt nichts, was uns "geh�rt". Wenn wir uns die vorigen zwei Bilder etwas genauer ansehen, f�llt aber etwas auf:

Beim Scroller_YUnlimited Algorithms geh�ren in unserem Beispiel sowohl Teile der oberen als auch Teile der unteren Bitmaph�lfte zum aktuellen/sichtbaren Bereich. Wie es der Zufall (oder auch nicht) will, ist der Teil, der zur unteren Bitmaph�lfte geh�rt (blaues Rechteck) identisch mit dem gleich gro�en Bereich am Anfang der oberen Bitmaph�lfte (gr�nes Rechteck). Und diesen Bereich gibt es in identischer Ausf�hrung auch bei unserer einfach-hohen-Bitmap = beim Scroller_YUnlimited2 Algorithmus.

Die L�sung w�re also, dem Videochip irgendwie zu sagen, da� er, wenn er am unteren Ende unserer Bitmap angelangt ist, einfach an den Bitmapanfang h�pft und den Rest des Screens ab da darstellt. Dank des Coppers ist das ganz einfach. Wir benutzen einfach eine COPWAIT Instruktion in der Copperliste, um auf den Anfang der Rasterzeile zu warten, die ohne unser Eingreifen Daten au�erhalb unserer Bitmap darstellen w�rde, und setzen dann die Planeadressen wieder an den Anfang der Bitmap. Die Zeile, auf die wir warten m�ssen �ndert sich beim Scrollen st�ndig, weil sich der aktuelle Bitmapbereich und somit auch der Bereich in der Bitmap, den wir zu Anfang der Copperliste durch entsprechendes Setzen der Planeadressen darstellen, st�ndig �ndert. Sind z. B. die Planeadressen am Anfang der Copperliste so gesetzt worden, da� sie die Bitmap ab Zeile 32 darstellen (hei�t: der aktuelle Bitmapbereich beginnt ab Zeile 16), dann wird der Videochip das Ende unserer Bitmap in Rasterzeile 256 (32 + 256 = 288 = BITMAPH�HE) erreicht (und �bersprungen) haben. Die Zeile, auf die wir warten m�ssen errechnet sich also wie folgt:

yoffset = Zeile, ab der wir die Bitmap am Anfang der Copperliste darstellen

zeile = DIWSTARTY + BITMAPH�HE - yoffset

DIWSTARTY mu� deshalb dazugez�hlt werden, weil die erste sichtbare Rasterzeile f�r den Videochip nicht 0 ist, sondern die Y Komponente des Display Window Start Hardware Registers. Bei COPWAIT Instruktionen ist noch zu beachten, da� nur 8 Bit (Werte zwischen 0 und 255) f�r die Y-Koordinate zur Verf�gung stehen. Will man auf eine Zeile warten, die gr��er gleich 256 ist, dann mu� man zuerst auf das Ende der Zeile 255 warten und dann auf die Zeile (ZEILE - 256).

Nach der COPWAIT Instruktion werden die Planeadressen alle an den Anfang der Bitmap gesetzt. Das hei�t immer auf den gleichen Wert, wir m�ssen sie also nicht st�ndig anpassen. Es reicht aus, sie einmal beim Initialisieren der Copperliste in dieselbe einzutragen.

Der Copper ben�tigt 2 Instruktionen, um eine Planeadresse zu setzen - eine f�r das HIWORD (obere 16 Bit) und eine f�r das LOWORD (untere 16 Bit). Bei Verwendung von vielen Planes kann es sein, da� der Copper in der horizontalen Austastl�cke nicht genug Zeit hat, um alle Planeadressen rechtzeitig zu setzen, also noch bevor die VideoDMA wieder beginnt, Daten aus dem CHIP RAM zu lesen. Das d�rfte sp�testens bei 7 oder 8 Planes passieren. Gl�cklicherweise gibt es einen Trick, mit dem wir nur die H�lfte an Copperinstruktionen ben�tigen:

Der Trick funktioniert so: Wir warten auf die Rasterzeile, die sich vor der errechneten Zeile befindet. In dieser Zeile �ndern wir die Bitplane Modulo Register, wobei wir das an jeder beliebigen (auch sichtbaren) horizontalen Stelle der Rasterzeile machen k�nnen. Durch das �ndern der Bitplane Moduli �ndern sich alle Planeadressen automatisch, sobald der VIDEO Chip in die n�chste Zeile springt. Den Wert, den wir in die Bitplane Modulo Register schreiben, w�hlen wir so, da� sich f�r die n�chste Zeile das richtige LOWORD f�r alle Planeadressen ergibt. Die Berechnung ist relativ einfach:

gew�nschteadresse = Anfang Bitmap f�r Plane 0

alteadresse = Adresse, die der Plane-0-Pointer am Ende von ZEILE - 1 erreichen wird

modulowert = (gew�nschteadresse - alteadresse) & 0xFFFF

Es ginge sogar noch einfacher, was dann aber nicht mehr so ganz einleuchtend aussieht. Bei nur-vertikalem Scrolling ist alteadresse konstant und entspricht stets der Plane0-Adresse der letzten Bitmapzeile + (BITMAPBREITE / 8). Das ist deshalb so, weil in Rasterzeile ZEILE - 1 stets die unterste Zeile unserer Bitmap dargestellt wird. Da sowohl alteadresse als auch gew�nschteadresse konstant sind, mu� folgerichtig auch das Ergebnis (modulowert) konstant sein. Im Demo-Quelltext befindet sich diese Berechnung deshalb in der InitCopperlist() Funktion. Durch das �ndern der Bitplane Moduli haben wir erst die LOWORDs der Bitplane Pointer ge�ndert (w�rde man eine nicht-interleavte Bitmap mit max. Planegr��e von 32 KByte oder eine entsprechend kleinere interleavte Bitmap mit max. Bitmapgr��e von 32 KByte verwenden, die dazu noch richtig aligned ist, dann ist es m�glich, durch Bitplane Modulo �nderung automatisch auch die HIWORDs richtig zu setzen). Um die HIWORDs zu setzen warten wir auf die n�chste Zeile, d. h. auf die Zeile die wir eigentlich errechnet hatten = den Anfang der Rasterzeile ZEILE. 1 Copperinstruktion pro Plane reicht jetzt aus. Nach den Planes setzen wir die Bitplane Modulo Register wieder auf den richtigen (alten) Wert. Wiederum ist es hier egal, wenn sich der Videobeam bereits im sichtbaren Bereich befindet. Alle diese Dinge, mit Ausnahme der COPWAIT Instruktionen, werden in der InitCopperlist() Funktion gemacht, weil sich an den Werten w�hrend des Scrollens nichts �ndert.

Noch einige Bemerkungen zum Quelltext des Demoprogrammes. Wenn die Variable mapposy, die die Levelposition Y in Pixeln enth�lt, auf 0 steht, dann sieht der User den Levelbereich ab Position BLOCKH�HE (16), weil die ersten BLOCKH�HE (16) Pixel stets verdeckt sind. Der User sieht also den Bereich:

(0,mapposy + BLOCKHEIGHT) - (SCREENWIDTH - 1,mapposy + BLOCKHEIGHT + SCREENHEIGHT - 1)

Das hei�t, da� die erste Blockreihe der Leveldatei nie sichtbar ist. Will man in die Bitmap etwas hineinblitten, z. B. Blitter Objekte (BOBs), dann mu� man das im aktuell sichtbaren Bitmapbereich machen. Dieser Bereich ist:

(0,(videoposy + BLOCKHEIGHT) % BITMAPHEIGHT) - (SCREENWIDTH - 1,(videoposy + BLOCKHEIGHT + SCREENHEIGHT - 1) % BITMAPHEIGHT)

Man darf die Start-Y Koordinate ((videoposy + BLOCKHEIGHT) % BITMAPHEIGHT) und die End-Y Koordinate ((videoposy + BLOCKHEIGHT + SCREENHEIGHT - 1) % BITMAPHEIGHT) auf ein Vielfaches von BLOCKHEIGHT auf- bzw. abrunden, soda� der Bereich, in den geblittet werden darf insgesamt SCREENHEIGHT + BLOCKHEIGHT Pixel hoch ist:

blitbereich_strty = ((videoposy + BLOCKHEIGHT) & ~(BLOCKHEIGHT - 1)) % BITMAPHEIGHT

blitbereich_endey = (blitbereich_strtx + SCREENHEIGHT + BLOCKHEIGHT - 1) % BITMAPHEIGHT

Wie aus obigen Berechnungen zu erahnen, kann es vorkommen, da� die Ende-Y-Koordinate �ber der Start-Y-Koordinate liegt, d. h. kleiner ist. Das liegt am Videosplitting und bedeutet nichts anderes, als da� der Bereich von der Startkoordinate bis zum Ende der Bitmap geht, dann an den Anfang der Bitmap "wrappt" und dort noch bis zur Endkoordinate reicht. F�r das Blitten in den Blitbereich folgt daraus, da� man sich die Blith�he und die errechnete Blit-Ziel-Y-Position (blitbereich_strty + ziely) genau anschauen mu�:

Wenn BLITZIELY + BLITH�HE <= BITMAPH�HE dann:
Ganz normal an Y-Position BLITZIELY blitten
andernfalls, wenn BLITZIELY >= BITMAPH�HE dann:
Ganz normal an Y-Position (BLITZIELY - BITMAPH�HE) blitten
andernfalls:
Die ersten (BITMAPH�HE - BLITZIELY) Pixelzeilen an Y-Position BLITZIELY blitten
Die letzten BLITH�HE - (BITMAPH�HE - BLITZIELY) Pixelzeilen an Y-Positionen 0 blitten

Im schlimmsten Fall, d. h. wenn sich die Videosplit-Zeile innerhalb des Blit-Ziel- Bereiches befindet, mu� der Blit also in zwei Schritten gemacht werden. Das ist nur l�stig, aber nicht weiter schlimm oder extrem langsam, zumal die Wahrscheinlichkeit, da� ein Objekt in zwei Schritten geblittet werden mu�, in den meisten F�llen ziemlich gering ist.